Technical Q&As


NW 11 - Obtaining a List of Volumes from a Server Programmatically (1-June-95)


Q How do I obtain a list of volumes from a server programmatically, given that I have the atalk-internet address of that server?

A To obtain a list of volumes from a server programatically, you use an AFPCommand called afpGetSParms. This command requires you to log in (as either a guest or a user) and create a session, and then issue the afpGetSParms. The string returned by afpGetSParms, which is described on page 13-98 of Inside AppleTalk, looks like this:

[0-3]	long	Current Date-time on Server's clock
[4]	byte	Number of Volumes that follow
---->	byte	NumVol Structure...
		Msb = HasPassword (bit) 
		Lsb = HasConfigInfo (appleII stuff, ignore it)
	P-String	Volume Name 
<----

The string is repeated for each volume.

There is also an example in the February 1995 Developer CD:

Dev.CD Feb 95:Sample Code:Snippets:Networking:AppleTalk Libraries

The string from this example looks like this:

short LogOnAsGuest(AddrBlock *serverAddress,Ptr SCBBlock)
  {
	AFPLoginPrm *XPPBlock;	/* to build parameter blocks for AFP */
	short 		cbsize;
	char		XPPReply[quantumSize*8]; /* used to get AFP replies (max. size 8 ATP packet) */
	char		XPPCmd[quantumSize]; /* used to send AFP commands */
	OSErr		error;
	short		result;
-	/* information used by Login function */
	char		AFPVersion[30];
	char		AuthentMethod[30];
	
	strcpy(AFPVersion, "AFPVersion 2.0");
	strcpy(AuthentMethod, "No User Authent");
	
	if (!(XPPBlock = (AFPLoginPrm *)NewPtrClear(sizeof(AFPLoginPrm))))
		return MemError();
	
	XPPBlock->ioRefNum = xppRefNum;
    XPPBlock->ioCompletion = nil;
 	XPPBlock->aspTimeout = 1;    /* Timeout for ATP */
 	XPPBlock->aspRetry = 2;      /* Retry count for ATP */
 	XPPBlock->afpAddrBlock = *serverAddress; /* AppleTalk address of the server */
 	XPPBlock->afpAttnRoutine = nil ;            
	XPPBlock->rbPtr = (Ptr)XPPReply; /* Reply buffer pointer */
	XPPBlock->rbSize = quantumSize;  /* Reply buffer size */
	
	/* prepare command information :
	   1st byte : command (login)
	   2nd Pascal string : AFP version
	   3rd Pascal string : Authentication Method - see Inside AppleTalk 13-104 */
	XPPCmd[0] = afpLogin;
	XPPCmd[1] = strlen(AFPVersion);
	strcpy(XPPCmd+2,AFPVersion);
	cbsize = strlen(XPPCmd);
	XPPCmd[cbsize] = strlen(AuthentMethod);
	strcpy(XPPCmd+cbsize+1,AuthentMethod);
	cbsize = strlen(XPPCmd);
	
    XPPBlock->cbPtr = (Ptr)XPPCmd; /* Command block pointer */
	XPPBlock->cbSize = cbsize;
	XPPBlock->afpSCBPtr = (Ptr) SCBBlock; /* SCB pointer in AFP login */

	if ((error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync)) != noErr)
		result = error;
	else
		if (XPPBlock->cmdResult != noErr)
		   result =  XPPBlock->cmdResult ;
	  	else result =  XPPBlock->sessRefnum;	/* return session number */
	
	DisposPtr((Ptr)XPPBlock);
	return result;
}	/* LogOnAsGuest */

OSErr GetServerParams(short sessNum,Ptr replyBuffer,short buffLength)
{
	XPPPrmBlk 	*XPPBlock; /* to build parameter blocks for AFP */
	char		XPPCmd[quantumSize];/* used to send AFP commands */
	OSErr		error;
	
	if (!(XPPBlock = (XPPPrmBlk *)NewPtrClear(sizeof(XPPPrmBlk))))
		return MemError();

	XPPBlock->ioRefNum = xppRefNum; /* driver reference number */
	/* prepare command information : 
		no input provided except command - see IA 13-98 */
 	XPPCmd[0]  = afpGetSParms;
	
	XPPBlock->sessRefnum = sessNum;
	XPPBlock->aspTimeout = 2; /* Timeout for ATP */
 	XPPBlock->aspRetry = 2; 
	XPPBlock->cbPtr = (Ptr)XPPCmd;
    XPPBlock->cbSize = 1;            /* Command block size */
	XPPBlock->rbPtr = replyBuffer;   /* Reply buffer pointer */
	XPPBlock->rbSize = buffLength;
  	XPPBlock->wdSize = 0;    /* Write Data size */
    XPPBlock->wdPtr = nil;      /* Write Data pointer */
	
	error = AFPCommand((XPPParmBlkPtr)XPPBlock,sync);
	DisposPtr((Ptr)XPPBlock);
	return error;
 }

main()
{

Str32				theServer;
Ptr					buffer;
AddrBlock 			serverAddress;
char				SCBBlock[scbMemSize];   /* used by AFP to manage a session */
short 				sessionNum;
OSErr 				ErrNo;
short 				refNum;

/* allocate a buffer to retrieve info */
	if (!(buffer = NewPtr(buffSize))) return;
		
/* open .XPP driver */
	ErrNo = OpenXPP(&refNum);

// hard coded address cause I'm lazy

	serverAddress.aNet = 41107;
	serverAddress.aNode = 87;
	serverAddress.aSocket = 250;
	

// simple login as guest
	if ((sessionNum = LogOnAsGuest(&serverAddress,&SCBBlock)) <= 0)	{		
		DisposePtr(buffer);
		return;
		}

// get server params
	if ((ErrNo = GetServerParams(sessionNum,buffer,buffSize)) != noErr) {
		DisposePtr(buffer);
		return;
		}

// buffer has server string


// be a good citizen
	LogOut(sessionNum,&SCBBlock);

	DisposePtr(buffer);
}


Technical Q&As
Previous Question | Contents | Next Question